﻿using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Interactivity;
using System.Windows.Media;

namespace Mandarine.Behavior
{
    public class NotifyOnValidationErrorBehavior : Behavior<FrameworkElement>
    {
        private static readonly Brush _errorBrush = new SolidColorBrush(Colors.Red);
        private readonly EventHandler<ValidationErrorEventArgs> _errorHandler;
        private readonly Dictionary<Control, Brush> _saveForgroundBrushes;
        private readonly Dictionary<Control, Brush> _saveBorderBrushes  ;

        /// <summary>
        /// デフォルトコンストラクタ
        /// </summary>
        public NotifyOnValidationErrorBehavior()
        {
            _saveForgroundBrushes = new Dictionary<Control, Brush>();
            _saveBorderBrushes = new Dictionary<Control, Brush>();

            _errorHandler = (s, e) =>
            {
                var control = e.OriginalSource as Control;

                if (control == null) return;

                if (e.Action == ValidationErrorEventAction.Added)
                {
                    _saveForgroundBrushes[control] = control.Foreground;
                    _saveBorderBrushes[control] = control.BorderBrush;
                    // エラーがスローされたら入力された値を赤い太字にする
                    control.Foreground = _errorBrush;
                    control.BorderBrush = _errorBrush;
                    control.FontWeight = FontWeights.Bold;
                }
                else if (e.Action == ValidationErrorEventAction.Removed)
                {
                    // エラースローされなければ値の表示を元に戻す
                    control.Foreground = _saveForgroundBrushes[control];
                    control.BorderBrush = _saveBorderBrushes[control];
                    control.FontWeight = FontWeights.Normal;
                }
            };
        }

        protected override void OnAttached()
        {
            // アタッチのタイミングでイベントを登録
            base.OnAttached();
            AssociatedObject.BindingValidationError += _errorHandler;
        }

        protected override void OnDetaching()
        {
            // 切り離されるタイミングでイベントの登録解除 
            AssociatedObject.BindingValidationError -= _errorHandler;
            _saveForgroundBrushes.Clear();
            _saveBorderBrushes.Clear();

            base.OnDetaching();
        }
    }
}